use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
    pub server: ServerConfig,
    pub database: DatabaseConfig,
    pub auth: AuthConfig,
    pub gateway: GatewayConfig,
    pub logging: LoggingConfig,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerConfig {
    pub host: String,
    pub port: u16,
    pub workers: usize,
    pub enable_cors: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseConfig {
    pub connection_string: String,
    pub max_connections: u32,
    pub min_connections: u32,
    pub connect_timeout: u64,
    pub idle_timeout: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfig {
    pub jwt_secret: String,
    pub token_expiry: u64,
    pub refresh_token_expiry: u64,
    pub password_hash_rounds: u32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GatewayConfig {
    pub default_timeout: u64,
    pub max_retries: u32,
    pub rate_limit_per_minute: u32,
    pub enable_circuit_breaker: bool,
    pub circuit_breaker_threshold: u32,
    pub circuit_breaker_timeout: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoggingConfig {
    pub level: String,
    pub format: String,
    pub enable_file_logging: bool,
    pub file_path: Option<String>,
    pub max_file_size: u64,
    pub max_files: usize,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            server: ServerConfig {
                host: "127.0.0.1".to_string(),
                port: 8080,
                workers: 4,
                enable_cors: true,
            },
            database: DatabaseConfig {
                connection_string: "postgresql://username:password@localhost:5432/gateway_db".to_string(),
                max_connections: 10,
                min_connections: 2,
                connect_timeout: 30,
                idle_timeout: 300,
            },
            auth: AuthConfig {
                jwt_secret: "your-secret-key".to_string(),
                token_expiry: 3600, // 1小时
                refresh_token_expiry: 2592000, // 30天
                password_hash_rounds: 12,
            },
            gateway: GatewayConfig {
                default_timeout: 30,
                max_retries: 3,
                rate_limit_per_minute: 1000,
                enable_circuit_breaker: true,
                circuit_breaker_threshold: 5,
                circuit_breaker_timeout: 60,
            },
            logging: LoggingConfig {
                level: "info".to_string(),
                format: "json".to_string(),
                enable_file_logging: false,
                file_path: None,
                max_file_size: 10485760, // 10MB
                max_files: 5,
            },
        }
    }
}

impl Config {
    pub fn load_from_file(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let content = std::fs::read_to_string(path)?;
        let config: Config = serde_yaml::from_str(&content)?;
        Ok(config)
    }

    pub fn save_to_file(&self, path: &str) -> Result<(), Box<dyn std::error::Error>> {
        let content = serde_yaml::to_string(self)?;
        std::fs::write(path, content)?;
        Ok(())
    }

    pub fn to_hashmap(&self) -> HashMap<String, String> {
        let mut map = HashMap::new();
        
        map.insert("server.host".to_string(), self.server.host.clone());
        map.insert("server.port".to_string(), self.server.port.to_string());
        map.insert("server.workers".to_string(), self.server.workers.to_string());
        map.insert("server.enable_cors".to_string(), self.server.enable_cors.to_string());
        
        map.insert("database.connection_string".to_string(), self.database.connection_string.clone());
        map.insert("database.max_connections".to_string(), self.database.max_connections.to_string());
        map.insert("database.min_connections".to_string(), self.database.min_connections.to_string());
        map.insert("database.connect_timeout".to_string(), self.database.connect_timeout.to_string());
        map.insert("database.idle_timeout".to_string(), self.database.idle_timeout.to_string());
        
        map.insert("auth.jwt_secret".to_string(), self.auth.jwt_secret.clone());
        map.insert("auth.token_expiry".to_string(), self.auth.token_expiry.to_string());
        map.insert("auth.refresh_token_expiry".to_string(), self.auth.refresh_token_expiry.to_string());
        map.insert("auth.password_hash_rounds".to_string(), self.auth.password_hash_rounds.to_string());
        
        map.insert("gateway.default_timeout".to_string(), self.gateway.default_timeout.to_string());
        map.insert("gateway.max_retries".to_string(), self.gateway.max_retries.to_string());
        map.insert("gateway.rate_limit_per_minute".to_string(), self.gateway.rate_limit_per_minute.to_string());
        map.insert("gateway.enable_circuit_breaker".to_string(), self.gateway.enable_circuit_breaker.to_string());
        map.insert("gateway.circuit_breaker_threshold".to_string(), self.gateway.circuit_breaker_threshold.to_string());
        map.insert("gateway.circuit_breaker_timeout".to_string(), self.gateway.circuit_breaker_timeout.to_string());
        
        map.insert("logging.level".to_string(), self.logging.level.clone());
        map.insert("logging.format".to_string(), self.logging.format.clone());
        map.insert("logging.enable_file_logging".to_string(), self.logging.enable_file_logging.to_string());
        map.insert("logging.file_path".to_string(), self.logging.file_path.clone().unwrap_or_default());
        map.insert("logging.max_file_size".to_string(), self.logging.max_file_size.to_string());
        map.insert("logging.max_files".to_string(), self.logging.max_files.to_string());
        
        map
    }
}

/// 全局配置加载函数
pub fn load_config() -> Result<Config, Box<dyn std::error::Error>> {
    let mut config = Config::load_from_file("config/config.yaml")
        .unwrap_or_else(|_| Config::default());
    
    // 应用环境变量覆盖
    config.apply_env_overrides();
    
    Ok(config)
}

impl Config {
    /// 应用环境变量覆盖配置
    pub fn apply_env_overrides(&mut self) {
        // 服务器配置覆盖
        if let Ok(host) = std::env::var("SERVER_HOST") {
            self.server.host = host;
        }
        if let Ok(port) = std::env::var("SERVER_PORT") {
            if let Ok(port_num) = port.parse::<u16>() {
                self.server.port = port_num;
            }
        }
        
        // 数据库配置覆盖
        if let Ok(conn_str) = std::env::var("DB_CONNECTION_STRING") {
            self.database.connection_string = conn_str;
        }
        
        // 认证配置覆盖
        if let Ok(jwt_secret) = std::env::var("JWT_SECRET") {
            self.auth.jwt_secret = jwt_secret;
        }
        
        // 日志配置覆盖
        if let Ok(log_level) = std::env::var("RUST_LOG") {
            self.logging.level = log_level;
        }
    }
    
    /// 从环境变量加载配置（主要用于Docker环境）
    pub fn from_env() -> Self {
        let mut config = Config::default();
        config.apply_env_overrides();
        config
    }
}